﻿// Copyright 2009 Mike Geise
// 
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// 
//     http://www.apache.org/licenses/LICENSE-2.0
// 
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

namespace Falcon.Core.Services
{
	using System;
	using System.Collections.Generic;
	using Falcon.Core.Collections;
	using Falcon.Core.Domain;
	using Falcon.Core.Domain.Repositories;
	using Falcon.Core.Domain.Services;
	using Falcon.Core.Domain.Values;

	public class UserSearchService : IUserSearchService
	{
		/// <summary>
		/// Initializes a new instance of the <see cref="UserSearchService"/> class.
		/// </summary>
		/// <param name="identityService">The identity service.</param>
		public UserSearchService(IIdentityService identityService)
		{
			this.IdentityService = identityService;
		}

		/// <summary>
		/// Gets or sets the identity service.
		/// </summary>
		/// <value>The identity service.</value>
		public IIdentityService IdentityService
		{
			get;
			private set;
		}

		/// <summary>
		/// Initializes a new instance of the <see cref="UserSearchService"/> class.
		/// </summary>
		/// <param name="userSearchRepository">The user search repository.</param>
		public UserSearchService(IUserSearchRepository userSearchRepository)
		{
			this.UserSearchRepository = userSearchRepository;
		}

		/// <summary>
		/// Gets or sets the user search repository.
		/// </summary>
		/// <value>The user search repository.</value>
		public IUserSearchRepository UserSearchRepository
		{
			get; 
			private set;
		}

		/// <summary>
		/// Gets all the recent searches.
		/// </summary>
		/// <param name="specification"></param>
		/// <returns></returns>
		public IList<UserSearch> GetAll(UserSearchSpecification specification)
		{
			return this.UserSearchRepository.GetAll(specification);
		}

		/// <summary>
		/// Gets all the users by the specified specification using paging.
		/// </summary>
		/// <param name="specification">The <see cref="UserSpecification"/>.</param>
		/// <returns></returns>
		public IPagedList<User, UserSearchSpecification> GetPaged(UserSearchSpecification specification)
		{
			this.Update(new UserSearch
			{
				Id = specification.Id
			});

			return this.UserSearchRepository.GetPaged(specification);
		}

		/// <summary>
		/// Creates the user search.
		/// </summary>
		/// <returns></returns>
		public UserSearch Create()
		{
			var search = new UserSearch
			{
				Created = DateTime.Now
			};

			search.Updated = search.Created;

			return search;
		}

		/// <summary>
		/// Inserts the specified search.
		/// </summary>
		/// <param name="search">The search.</param>
		public void Insert(UserSearch search)
		{
			this.UserSearchRepository.Insert(search);
		}

		/// <summary>
		/// Inserts the specified search.
		/// </summary>
		/// <param name="search">The search.</param>
		/// <param name="value">The value.</param>
		public void Insert(UserSearch search, UserSearchCreate value)
		{
			value.Validate();

			if (value.Save)
			{
				var identity = IdentityService.Current;

				if (identity != null && identity.IsAuthenticated)
				{
					search.UserId = identity.Id;
					search.Title = value.Title;
				}
			}

			search.Name = value.Name;
			search.EmailAddress = value.EmailAddress;
			search.HostAddress = value.HostAddress;
			search.CreatedAfter = value.CreatedAfter;
			search.CreatedBefore = value.CreatedBefore;
			search.LastVisitAfter = value.LastVisitAfter;
			search.LastVisitBefore = value.LastVisitBefore;
			search.PostsGreaterThanOrEqual = value.PostsGreaterThanOrEqual;
			search.PostsLessThanOrEqual = value.PostsLessThanOrEqual;
			search.ReputationGreaterThanOrEqual = value.ReputationGreaterThanOrEqual;
			search.ReputationLessThanOrEqual = value.ReputationLessThanOrEqual;

			this.Insert(search);
		}

		/// <summary>
		/// Updates the specified search.
		/// </summary>
		/// <param name="search">The search.</param>
		public void Update(UserSearch search)
		{
			search.Validate();

			search.Updated = DateTime.Now;

			this.UserSearchRepository.Update(search);
		}

		/// <summary>
		/// Deletes the expired search results.
		/// </summary>
		public void DeleteExpired()
		{
			this.UserSearchRepository.DeleteExpired();
		}
	}
}